﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Text;

namespace Apewer
{

    /// <summary></summary>
    public sealed class Enumerator<T> : IEnumerator<T>, IEnumerator, IDisposable
    {

        // 类的状态
        bool _disposed = false;
        string _type;

        // 元素获取
        Func<int, Class<T>> _getter = null;

        // 迭代器
        int _index = 0;
        T _current = default;

        #region IDisposable

        /// <summary></summary>
        public void Dispose()
        {
            _disposed = true;
        }

        #endregion

        #region IEnumerator<T>

        /// <summary></summary>
        public T Current
        {
            get
            {
                if (_disposed) throw new ObjectDisposedException(_type);
                return _current;
            }
        }

        #endregion

        #region IEnumerator

        /// <summary></summary>
        object IEnumerator.Current { get => Current; }

        /// <summary></summary>
        public bool MoveNext()
        {
            if (_disposed) throw new ObjectDisposedException(_type);

            var value = _getter(_index);
            if (value == null) return false;

            _current = value.Value;
            _index++;
            return true;
        }

        /// <summary></summary>
        public void Reset()
        {
            if (_disposed) throw new ObjectDisposedException(_type);
            _current = default;
            _index = 0;
        }

        #endregion

        /// <summary>创建枚举器实例。</summary>
        /// <param name="getter">元素获取程序。传入参数为索引值，从 0 开始；枚举结束后应返回 NULL 值。</param>
        /// <exception cref="ArgumentNullException" />
        public Enumerator(Func<int, Class<T>> getter)
        {
            if (getter == null) throw new ArgumentNullException(nameof(getter));
            _getter = getter;
            _type = GetType().Name;
            Reset();
        }

    }

}
